package com.jcn.seckill.exception;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jcn.seckill.result.CodeMsg;
import com.jcn.seckill.result.Result;

//可以将对于控制器的全局配置放在同一个位置
@ControllerAdvice
/**
 * 返回结果直接写入 HTTP response body 中，
 * 一般在异步获取数据时使用【也就是AJAX】，
 * 在使用 @RequestMapping后，返回值通常解析为跳转路径，
 * 但是加上 @ResponseBody 后返回结果不会被解析为跳转路径，
 * 而是直接写入 HTTP response body 中。 比如异步获取 json 数据，
 * 加上 @ResponseBody 后，会直接返回 json 数据。@RequestBody 
 * 将 HTTP 请求正文插入方法中，
 * 使用适合的 HttpMessageConverter 将请求体写入某个对象。
 * */
@ResponseBody
public class GlobalExceptionHandler {
	//用于全局处理控制器里的异常
	@ExceptionHandler(value=Exception.class)
	public Result<String> exceptionHandler(HttpServletRequest request, Exception e){
		e.printStackTrace();
		//如果异常是绑定异常
		if(e instanceof GlobalException) {
			//获取业务异常
			GlobalException ex = (GlobalException)e;
			return Result.error(ex.getCm());
		}else if(e instanceof BindException) {
			BindException ex = (BindException)e;
			List<ObjectError> errors = ex.getAllErrors();
			//取得第一个异常信息
			ObjectError error = errors.get(0);
			String msg = error.getDefaultMessage();
			//将错误信息传递给绑定异常将错误信息带出去
			return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg));
		}else {
			//通用服务端异常
			return Result.error(CodeMsg.SERVER_ERROR);
		}
	}
}
